package org.light.facade;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.javaforever.gatescore.action.ParseSpreadSheetToProjectAction;
import org.javaforever.poitranslator.core.ProjectExcelWorkBook;
import org.light.domain.Project;
import org.light.domain.ValidateInfo;
import org.light.exception.ValidateException;
import org.light.utils.StringUtil;
import org.light.wizard.ExcelWizard;

import com.hmkcode.vo.FileMeta;

import net.sf.json.JSONObject;

/**
 * 
 * @author Jerry Shen 2021.2.8
 *
 */
public class GenerateFromExcelWizardFacade extends HttpServlet {
	private static final long serialVersionUID = 4481920243656582501L;
	private static List<FileMeta> files = new LinkedList<FileMeta>();

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public GenerateFromExcelWizardFacade() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}

	protected Map<String,String> generateZip(String root, String filepath, boolean ignoreWarning,boolean genFormatted,boolean genUi,boolean genController,boolean genService,boolean genServiceImpl,boolean genDao,boolean genDaoImpl,boolean sqlComments) throws Exception {
		InputStream is = null;
		POIFSFileSystem fs = null;
		Map<String, Object> result = new TreeMap<String, Object>();
		// request.setCharacterEncoding("UTF-8");
		File f2 = null;
		try {
			// deal with uploaded excel sheet
			String sourcefolder = root + "source/";
			f2 = new File(filepath);

			is = new FileInputStream(f2);
			fs = new POIFSFileSystem(is);
			HSSFWorkbook wb = new HSSFWorkbook(fs);
			ProjectExcelWorkBook pewb = new ProjectExcelWorkBook();

			Project project = pewb.translate(wb,ignoreWarning);
			project.setExcelTemplateName(f2.getName());
			project.setExcelTemplateFolder(root + "spreadsheets/");
			project.setSqlCommentsOn(sqlComments);

			project.setFolderPath(sourcefolder);
			if (project.getTechnicalstack() == null || "".equalsIgnoreCase(project.getTechnicalstack())
					|| "sbmeu".equalsIgnoreCase(project.getTechnicalstack())|| "msmeu".equalsIgnoreCase(project.getTechnicalstack())|| "smeu".equalsIgnoreCase(project.getTechnicalstack())) {
				project.setSourceFolderPath((root + "templates/").replace('\\', '/'));
				project.generateProjectZip(ignoreWarning,genFormatted,genUi,genController,genService,genServiceImpl,genDao,genDaoImpl);
				
				Map<String,String> retMap = new HashMap<String,String>();
				retMap.put("projectName", project.getStandardName());
				retMap.put("schema", project.getSchema());

				return retMap;
			} else {
				throw new ValidateException("技术栈设置错误！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof ValidateException) {
				throw e;
			}
			return null;
		} finally {
			if (is != null) {
				is.close();
				is = null;
			}
			if (fs != null) {
				fs.close();
				fs = null;
			}
		}
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		InputStream input = null;
		OutputStream output = null;
		InputStream is = null;
		POIFSFileSystem fs = null;
		response.setContentType("text/plain;charset=UTF-8");
		PrintWriter out = response.getWriter();
		Map<String, Object> result = new TreeMap<String, Object>();
		// request.setCharacterEncoding("UTF-8");
		File f = null;
		try {

			String root = request.getSession().getServletContext().getRealPath("/").replace('\\', '/');

			String excelfolder = root + "spreadsheets/";
			excelfolder = excelfolder.replace('\\', '/');

			String ignoreWarning = request.getParameter("ignoreWarning");
			String genFormatted = request.getParameter("genFormatted");
			String generateFront = request.getParameter("generateFront");
			String frontUseProjectName = request.getParameter("frontUseProjectName");
			String frontUseControllerPrefix = request.getParameter("frontUseControllerPrefix");
			String sqlComments = request.getParameter("sqlComments");
			
			String useAdvancedCustomize=request.getParameter("useAdvancedCustomize");
			String genUiStr=request.getParameter("gemUi");
			String genControllerStr=request.getParameter("genController");
			String genServiceStr=request.getParameter("genService");
			String genServiceImplStr=request.getParameter("genServiceImpl");
			String genDaoStr=request.getParameter("genDao");
			String genDaoImplStr=request.getParameter("genDaoImpl");
			
			String genExcelFile = ExcelWizardFacade.getInstance().getExcelTemplateName();
			if (StringUtil.isBlank(genExcelFile)) genExcelFile="gen.xls";
			ExcelWizard.outputExcelWorkBook(ExcelWizardFacade.getInstance(), excelfolder,genExcelFile);
			
			f = new File(excelfolder + genExcelFile);
			boolean genUi = true;
			boolean genController=true;
			boolean genService = true;
			boolean genServiceImpl = true;
			boolean genDao = true;
			boolean genDaoImpl = true;
			if ("true".equalsIgnoreCase(useAdvancedCustomize)) {
				genUi = "true".equalsIgnoreCase(genUiStr);
				genController = "true".equalsIgnoreCase(genControllerStr);
				genService = "true".equalsIgnoreCase(genServiceStr);
				genServiceImpl = "true".equalsIgnoreCase(genServiceImplStr);
				genDao = "true".equalsIgnoreCase(genDaoStr);
				genDaoImpl = "true".equalsIgnoreCase(genDaoImplStr);
			}
			
			// Generate source zip file
			Map<String,String> generatedMap = generateZip(root, f.getPath(),"true".equalsIgnoreCase(ignoreWarning),"true".equalsIgnoreCase(genFormatted),genUi,genController,genService,genServiceImpl,genDao,genDaoImpl,"true".equalsIgnoreCase(sqlComments));

			boolean sqlOnly = false;
			if (generatedMap!=null&&generatedMap.get("schema")!=null)sqlOnly =  "DBTools".equalsIgnoreCase(generatedMap.get("schema"));

			String frontZipName = "";
			if ("true".equalsIgnoreCase(generateFront)&&!sqlOnly)
				frontZipName = ParseSpreadSheetToProjectAction.doParseExcel(excelfolder, genExcelFile, root + "templates/",
						root + "source/", "true".equalsIgnoreCase(frontUseProjectName), true, "true".equalsIgnoreCase(frontUseControllerPrefix));
			if (!StringUtil.isBlank(generatedMap.get("projectName"))) {
				result.put("success", true);
				result.put("projectName", generatedMap.get("projectName"));
				result.put("frontProjectName", frontZipName);
				out.print(JSONObject.fromObject(result));
			} else {
				throw new ValidateException("文件生成错误！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof ValidateException) {
				ValidateException ev = (ValidateException) e;
				result.put("success", false);
				ValidateInfo info = ev.getValidateInfo();
				List<String> compileErrors = info.getCompileErrors();
				result.put("compileErrors", compileErrors);
				List<String> compileWarnings = info.getCompileWarnings();
				result.put("compileWarnings", compileWarnings);
				out.print(JSONObject.fromObject(result));
				return;
			}
			if (!(e instanceof ValidateException)) {
				e.printStackTrace();
				result.put("success", false);
				if (e.getMessage() != null && !e.getMessage().equals("")) {
					result.put("compileErrors", new ArrayList<String>().add(e.getMessage()));
				} else {
					result.put("compileErrors", new ArrayList<String>().add("空指针或其他语法错误！"));
				}
				out.print(JSONObject.fromObject(result));
			}
		} finally {
			if (input != null)
				input.close();
			if (output != null)
				output.close();
			if (is != null)
				is.close();
			if (fs != null)
				fs.close();
			if (out != null)
				out.close();
		}
	}
}
